﻿using System;
using System.Collections.Generic;
using Bettzueche.RLLibrary.Types;

namespace Bettzueche.Dampfross
{
    /// <summary>
    /// Eine speichereffiziente Matrix von (q,e)-Tupeln
    /// </summary>
    [Serializable]
    class QEMatrix
    {
        #region Fields

        Dictionary<int, WETupel>[] _qeMatrix;
        #endregion


        #region Properties, Indexer

        /// <summary>
        /// Gets the number of rows (states)
        /// </summary>
        /// <value>
        /// The rows.
        /// </value>
        public int Rows { get; private set; }

        /// <summary>
        /// Gets the number of columns (actions).
        /// </summary>
        /// <value>
        /// The columns.
        /// </value>
        public int Columns { get; private set; }

        /// <summary>
        /// Gets or sets the <see cref="WETupel"/> with the specified (state, aktion) identifier.
        /// </summary>
        /// <value>
        /// The <see cref="WETupel"/>.
        /// </value>
        /// <param name="stateID">The state identifier.</param>
        /// <param name="aktion">The aktion.</param>
        /// <returns></returns>
        /// <exception cref="System.IndexOutOfRangeException">
        /// stateID war negativ!
        /// or
        /// stateID war größer-gleich Rows!
        /// </exception>
        public WETupel this[int stateID, HexRichtungen aktion] {
            get {
                if (stateID < 0) {
                    throw new IndexOutOfRangeException("stateID war negativ!");
                }
                if (stateID >= Rows) {
                    throw new IndexOutOfRangeException("stateID war größer-gleich Rows!");
                }
                if (_qeMatrix[(int)aktion].ContainsKey(stateID)) {
                    var we = _qeMatrix[(int)aktion][stateID];
                    return we;
                }
                else {
                    return new WETupel();
                }
            }
            set {
                if (stateID < 0) {
                    throw new IndexOutOfRangeException("stateID war negativ!");
                }
                if (stateID >= Rows) {
                    throw new IndexOutOfRangeException("stateID war größer-gleich Rows!");
                }
                _qeMatrix[(int)aktion][stateID] = value;
            }
        }

        #endregion

        
        #region Konstruktor(en)
        /// <summary>
        /// Initializes a new instance of the <see cref="QEMatrix"/> class.
        /// </summary>
        /// <param name="rows">The number of rows, states respectively.</param>
        /// <param name="cols">The number of columns, actions respectively.</param>
        public QEMatrix(int rows, int cols) {
            Rows = rows;
            Columns = cols;
            int capacity = rows >> 1;
            int anzAktionen = 6; // Enum.GetValues(typeof(HexRichtungen)).Length;
            _qeMatrix = new Dictionary<int, WETupel>[anzAktionen];
            for (int a = 0; a < anzAktionen; a++) {
                _qeMatrix[a] = new Dictionary<int, WETupel>(capacity);
            }
        }
        #endregion


        #region Methoden
        #endregion
    }
}
